/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#include "StdAfx.h"
#include "IrrFontManager.h"
#include "IrrFont.h"
#include "IRender.h"
#include "../shared/StringUtil.h"

#include "../Kernel.h"

extern Kernel* g_kernel;


/** Destroy the font */
void FontType::Destroy() 
{
    if ( m_ttFont ) delete m_ttFont;
    if ( m_ttFace ) delete m_ttFace;
}

IrrFontManager::IrrFontManager(void)
{
    m_colors[0].Set( 0, 0, 0, 1);                   // black
    m_colors[1].Set( 1, 1, 1, 1);                   // white
    m_colors[2].Set( 0.23f, 0.23f, 0.23f, 1);       // grey
    m_colors[3].Set( 1, 0, 0, 1);                   // red
    m_colors[4].Set( 0, 1, 0, 1);                   // green
    m_colors[5].Set( 0, 0, 1, 1);                   // blue
    m_colors[6].Set( 0.89f, 0.52f, 0.12f, 1);       // orange
    m_colors[7].Set( 0.65f, 0.03f, 0.65f, 1);       // purple
    m_colors[8].Set( 0.23f, 0.89f, 0.89f, 1);       // light blue
    m_colors[9].Set( 0.52f, 1, 0.52f, 1);           // light green

    m_currentFont = NULL;
}

IrrFontManager::~IrrFontManager(void)
{
    FreeAll();
}

/** Free all */
void IrrFontManager::FreeAll()
{
    type_FontList::iterator it = m_fonts.begin();
    for( ; it != m_fonts.end(); ++it )
    {
        (*it).second->Destroy();
        delete (*it).second;
    }
    m_fonts.clear();
}

/** Create a font */
bool IrrFontManager::Create( irr::video::IVideoDriver* irrVideo, const std::string &file, const std::string &fontName )
{
    FontType* font = new FontType;

    font->m_ttFace = new irr::gui::CGUITTFace;
    font->m_ttFace->load( file.c_str() );

    font->m_ttFont = new irr::gui::CGUITTFont( irrVideo );
    if ( !font->m_ttFont->attach( font->m_ttFace, DEFAULT_FONT_SIZE ) ) 
    {
        font->Destroy();
        delete font;
        return false;
    }

    font->height = font->m_ttFont->getDimension( L"f" ).Height;       //  defaults
    font->width  = font->m_ttFont->getDimension( L"w" ).Width;
    font->size   = DEFAULT_FONT_SIZE;
    font->name   = fontName;


    m_fonts[ fontName ] = font;

    if ( !m_currentFont )
        m_currentFont = font;

    return true;
}

/** Set Font Type */
void IrrFontManager::SetFontType( const std::string &fontName )
{
    if ( m_fonts.find( fontName ) != m_fonts.end() )
        m_currentFont = m_fonts[ fontName ];
    
}

/** Set the font size */
void IrrFontManager::SetFontSize( float size )
{
    if( m_currentFont )
    {
        m_currentFont->m_ttFont->attach( m_currentFont->m_ttFace, size );
        m_currentFont->size = size;
    }
}

/** Get the width of the text */
int IrrFontManager::GetWidth(char c) 
{ 
    return m_currentFont ? m_currentFont->m_ttFont->getWidthFromCharacter( c ) : 0; 
}

/** Get the height of the text */
int IrrFontManager::GetHeight(char c) 
{ 
    return m_currentFont ? m_currentFont->height : 0; 
}

/** Enable AntiAliasing */
void IrrFontManager::Antialias( bool b )
{ 
    if (m_currentFont) 
        m_currentFont->m_ttFont->AntiAlias = b; 
}

/** Free the font */
void IrrFontManager::Free(const std::string &fontName)
{
    type_FontList::iterator it = m_fonts.find( fontName );
    if ( it != m_fonts.end() )
    {
        m_fonts[ fontName ]->Destroy();
        delete m_fonts[ fontName ];
        m_fonts.erase( it );
    } 
}

/** Draw a String */
void IrrFontManager::DrawString( IRender* r, float x, float y, const char* s,... )
{
	char		text[1024];								// Holds Our String
	va_list		ap;										// Pointer To List Of Arguments

    if (s   == NULL)									// If There's No Text
		return;											// Do Nothing

    if ( !m_currentFont )                               // No Font Loaded
        return;

	va_start(ap, s);									// Parses The String For Variables
	    vsprintf(text, s, ap);							// And Converts Symbols To Actual Numbers
	va_end(ap);											// Results Are Stored In Text

    std::wstring str = StringUtil::ToWString( text );

    int currentColor = -1;
    for ( int i = 0; i< str.length(); ++i )
    {
        // check for a color changer
        if ( str[i] == '^' )
        {
            if ( i < str.length()-2 )
            {
                char c = str[i+1];
                if ( c >= 48 && c <= 57 ) {
                    currentColor =  c - 48;
                    i += 1; continue;
                }
            }
        }
        DrawChar( r, currentColor, x, y, str[i] );
        x += m_currentFont->m_ttFont->getWidthFromCharacter( str[i] );
    }
}

/** Draw out a single char */
void IrrFontManager::DrawChar( IRender* r, int color, float x, float y, const wchar_t c  )
{
    irr::video::SColorf scolor;
    if (color > -1) 
        scolor.set( m_colors[ color ][0], m_colors[ color ][1], m_colors[ color ][2]  );           // set the proper color
         
    else {
        Vector4f rc = r->GetColor();
        scolor.set( rc[0], rc[1], rc[2] );
    }
    m_currentFont->m_ttFont->drawChar( c, irr::core::rect<int>( x, y, 12, 12 ), scolor.toSColor() );     
}